package org.jetlinks.pro.device.service.task;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import org.hswebframework.web.id.IDGenerator;
import org.jetlinks.core.message.DeviceMessage;
import org.jetlinks.core.message.MessageType;
import org.jetlinks.pro.PropertyConstants;
import org.jetlinks.pro.device.enums.TaskState;

import java.util.Map;

@Getter
@Setter
public class DeviceMessageTask {

    @Schema(description = "唯一标识")
    private String id;

    @Schema(description = "发送指令的服务节点ID")
    private String serverId;

    @Schema(description = "产品ID")
    private String productId;

    @Schema(description = "设备ID")
    private String deviceId;

    @Schema(description = "设备名称")
    private String deviceName;

    @Schema(description = "消息ID")
    private String messageId;

    @Schema(description = "消息类型")
    private MessageType messageType;

    @Schema(description = "下行消息内容")
    private Map<String, Object> downstream;

    @Schema(description = "上行回复内容")
    private Map<String, Object> upstream;

    @Schema(description = "消息状态")
    private TaskState state;

    /**
     * @see org.jetlinks.core.enums.ErrorCode
     */
    @Schema(description = "错误码")
    private String lastErrorCode;

    @Schema(description = "错误信息")
    private String lastError;

    @Schema(description = "重试次数")
    private long retryTimes;

    @Schema(description = "最大重试次数")
    private long maxRetryTimes;

    @Schema(description = "发送时间")
    private long sendTimestamp;

    @Schema(description = "回复时间")
    private long replyTimestamp;

    public static DeviceMessageTask newTask(DeviceMessage downstream) {
        DeviceMessageTask task = new DeviceMessageTask();
        String taskId = downstream
            .getHeader(PropertyConstants.taskId)
            .orElseGet(IDGenerator.UUID::generate);
        downstream.addHeaderIfAbsent(PropertyConstants.taskId, taskId);

        task.setId(taskId);
        task.setDeviceId(downstream.getDeviceId());
        task.setDeviceName(downstream.getHeader(PropertyConstants.deviceName).orElse(downstream.getDeviceId()));
        task.setProductId(downstream.getHeader(PropertyConstants.productId).orElse("unknown"));
        task.setServerId(downstream.getHeader(PropertyConstants.serverId).orElse("unknown"));
        task.setSendTimestamp(downstream.getTimestamp());
        task.setMessageId(downstream.getMessageId());
        task.setMaxRetryTimes(downstream.getHeaderOrDefault(PropertyConstants.maxRetryTimes));
        task.setDownstream(downstream.toJson());
        task.setMessageType(downstream.getMessageType());
        task.setState(TaskState.processing);
        return task;
    }

    public DeviceMessage downstreamToMessage() {
        downstream.put("timestamp",System.currentTimeMillis());
        DeviceMessage message = messageType.convert(downstream);
        message.addHeader(PropertyConstants.taskId, getId());
        message.addHeader(PropertyConstants.useTask, true);

        return message;
    }
}
